/**
 * elancom Corporation copy right 2012 - 2015  
 *   
 * $Header$
 * $Id$
 * $Author$
 * $Date$
 * $Revision$
 */
package com.elancom.framework.component.interceptor;

import java.util.List;

import com.elancom.framework.component.Component;
import com.elancom.framework.component.ComponentException;
import com.elancom.framework.component.Input;
import com.elancom.framework.component.Invocation;
import com.elancom.framework.component.Output;
import com.elancom.framework.component.event.AfterEvent;
import com.elancom.framework.component.event.AfterListener;
import com.elancom.framework.component.event.BeforeEvent;
import com.elancom.framework.component.event.BeforeListener;
import com.elancom.framework.component.event.EventListenerSupport;

/**
 * @author elancom
 * @date 2012-8-22
 */
public class FireEventInterceptor implements Interceptor {

	/*
	 * (non-Javadoc)
	 * @see com.elancom.framework.component.interceptor.Interceptor#intercept(com.elancom.framework.component.Invocation)
	 */
	@Override
	public Object intercept(Invocation invocation) throws ComponentException {
		Component component = invocation.getContext().getComponent();
		if (!(component instanceof EventListenerSupport)) {
			return invocation.invoke();
		}

		Input input = invocation.getContext().getInput();
		Output output = invocation.getContext().getOutput();

		EventListenerSupport support = (EventListenerSupport) component;
		List<BeforeListener> beforeListeners = support.getBeforeListeners();
		List<AfterListener> afterListeners = support.getAfterListeners();

		if (beforeListeners != null && !beforeListeners.isEmpty()) {
			BeforeEvent event = new BeforeEvent(input, output);
			for (BeforeListener listener : beforeListeners) {
				listener.onBefore(event);
			}
		}

		Object rs = null;
		try {
			rs = invocation.invoke();
		} catch (Throwable throwable) {
			// processException(throwable);
			throw throwable;
		} finally {
		}

		if (afterListeners != null && !afterListeners.isEmpty()) {
			AfterEvent event = new AfterEvent(input, output);
			for (AfterListener listener : afterListeners) {
				listener.onAfter(event);
			}
		}

		return rs;
	}
}
